package com.yj.core.config.datasource;

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.EnumTypeHandler;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

@Slf4j
@Configuration
@MapperScan(basePackages = {"com.yj.*.api.mapper"})
public class DataSourceConfig {


    @Autowired
    private DataSourceTransactionManager transactionManager;

    @Value("${spring.profiles.active:dev}")
    private String active;

    private static final String ACTIVE_DEV = "dev";
    private static final String ACTIVE_TEST = "test";

    @Bean(name = "sqlSessionFactory")
    public MybatisSqlSessionFactoryBean sqlSessionFactory() {
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(transactionManager.getDataSource());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Set<Resource> result = new LinkedHashSet<>(16);
        try {
            result.addAll(Arrays.asList(resolver.getResources("classpath:mapper/*/*.xml")));
            result.addAll(Arrays.asList(resolver.getResources("classpath*:config/mapper/*/*.xml")));
            result.addAll(Arrays.asList(resolver.getResources("classpath*:config/mapper/*.xml")));
        } catch (Exception e){
            log.warn("获取【classpath:mapper/*/*.xml】资源错误!");
        }
        mybatisSqlSessionFactoryBean.setMapperLocations(result.toArray(new Resource[0]));
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setMapUnderscoreToCamelCase(true);

        if (ACTIVE_DEV.equals(active) || ACTIVE_TEST.equals(active)){
            mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        } else {
            mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.log4j2.Log4j2Impl.class);
        }
        //乐观锁配置
        mybatisConfiguration.addInterceptor(new OptimisticLockerInterceptor());
        mybatisConfiguration.setDefaultEnumTypeHandler(org.apache.ibatis.type.BaseTypeHandler.class);
        mybatisConfiguration.setMapUnderscoreToCamelCase(true);

        //设置枚举类型映射用 name
        mybatisConfiguration.setDefaultEnumTypeHandler(EnumTypeHandler.class);

        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);

        GlobalConfig globalConfig = new GlobalConfig();

        //配置DbConfig
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        // 主键策略配置
        dbConfig.setIdType(IdType.AUTO);
        globalConfig.setDbConfig(dbConfig);
        globalConfig.setMetaObjectHandler(new MetaObjectHandlerConfig());

        mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig);

        return mybatisSqlSessionFactoryBean;
    }

    @Bean(name = "namedParameterJdbcTemplate")
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate(){
        return new NamedParameterJdbcTemplate(transactionManager.getDataSource());
    }

    @Bean(name = "jdbcTemplate")
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(transactionManager.getDataSource());
    }
}
